<?php
/**
 *
 * User: wesley
 * Date: 2017/11/9 0009
 * Time: 9:36
 * Email: wu93wesley@foxmail.com
 */

namespace app\api\controller;

use think\Image;
use think\Request;
use think\Controller;
use think\Validate;


class Common extends Controller {
    protected $request;//用来处理参数
    protected $validater;//用来验证数据/参数
    protected $params;//过滤后符合要求的参数
    protected $rules = array(
        'User' => array(
            'login' => array(
                'user_name' => 'require',
                'user_pwd' => 'require|length:32',//md5加密之后就是32位
            ),
            'register' => array(
                'user_name' => 'require',
                'user_pwd' => 'require|length:32',//md5加密之后就是32位
                'code' => 'require|number|length:6',
            ),
            'upload_head_img' => array(
                'user_id' => 'require',
                'user_icon' => 'require|image|fileSize:20000000000|fileExt:jpg,png,bmp,jpeg',
            ),
            'change_pwd' => array(
                'user_name' => 'require',
                'user_ini_pwd' => 'require|length:32',
                'user_pwd' => 'require|length:32'
            ),
            'find_pwd' => array(
                'user_name' => 'require',
                'code' => 'require|number|length:6',
                'user_pwd' => 'require|length:32'
            ),
            'bind_phone' => array(
                'user_id' => 'require|number',
                'code' => 'require|number|length:6',
                'phone' => [ 'require', 'regex' => '/^1[34578]\d{9}$/' ],
            ),
            'bind_email' => array(
                'user_id' => 'require|number',
                'code' => 'require|number|length:6',
                'email' => 'require|email'
            ),
            'set_nickname' => array(
                'user_id' => 'require|number',
                'user_nickname' => 'require|chsDash'
            ),
        ),
        'Code' => array(
            'get_code' => array(
                'username' => 'require',
                'is_exist' => 'require|length:1|number',
            ),
        ),
        'Article' => array(
            'add_article' => array(
                'article_uid' => 'require|number',
                'article_title' => 'require|chsDash'
            ),
            'article_list' => array(
                'user_id' => 'require|number',
                'num' => 'number',
                'page' => 'number'
            ),
            'article_detail' => array(
                'article_id' => 'require|number',
            ),
            'update_article' => array(
                'article_id' => 'require|number',
                'article_title'=>'chsDash'
            ),
            'del_article' => array(
                'article_id' => 'require|number',
            )
        )
    );

    protected function _initialize () {
        parent::_initialize();
        $this->request = Request::instance();
//        $this->check_time($this->request->only([ 'time' ]));
//        $this->check_token($this->request->param());
        $this->params = $this->check_params($this->request->param(true));

    }

    /**
     * 验证请求是否超时
     * @param [array]  $arr  【包含时间戳的参数数组】
     * @return [json]    【检测结果】
     */
    public function check_time ($arr) {
        //判读时间戳是否存在
        if (!isset($arr[ 'time' ]) || intval($arr[ 'time' ]) <= 1) {
            $this->message(400, '时间戳不正确！');
        }
        if (time() - intval($arr[ 'time' ]) > 60) {
            $this->message(400, '请求超时');
        }
    }

    /**
     * api  数据返回
     * @param $code [int]  【结果码 200：正常  4**数据问题  5**服务器问题】
     * @param string $msg [string]  【接口返回的提升信息】
     * @param array $data [array]  【接口要返回的数据】
     * @return [string]    【最终的json数据】
     */
    public function message ($code, $msg = '', $data = []) {
        /** 数据组合**/
        $message_res[ 'code' ] = $code;
        $message_res[ 'msg' ] = $msg;
        $message_res[ 'data' ] = $data;
        /** 返回信息并终止脚步**/
        echo json_encode($message_res);
        die;
    }

    /**
     * 验证token值(防止篡改数据)
     * @param $arr [array] 【全部请求参数】
     * @return  [json]   【token验证结果】
     */
    public function check_token ($arr) {
        /** API传过来的token**/
        if (!isset($arr[ 'token' ]) || empty($arr[ 'token' ])) {
            $this->message(400, 'token不能为空');
        }
        $app_token = $arr[ 'token' ];//API传过来的token
        /** 服务器端生成的token*/
        unset($arr[ 'token' ]);
        $service_token = '';
        //循环将参数进行MD5加密并拼接
        foreach ($arr as $key => $value) {
            $service_token .= md5($value);
        }
        $service_token = md5('api_' . $service_token . '_api');//服务器端即时生成的token
//        dump($service_token);
//        die;
        /** 对比token，返回结果*/
        if ($app_token !== $service_token) {
            $this->message(400, 'token值不正确');
        }
    }

    /**
     * 检查参数
     * @param $arr [array]  【除time和token的所有参数】
     * @return [return]  【合格的参数数组】
     */
    public function check_params ($arr) {
        /** 获取参数的验证规则*/
        $rule = $this->rules[ $this->request->controller() ][ $this->request->action() ];
        /** 验证参数并返回错误*/
        $this->validater = new Validate($rule);
        if (!$this->validater->check($arr)) {
            $this->message(400, $this->validater->getError());
        }
        /** 如果正常，通过验证*/
        return $arr;
    }

    /**
     * 检测用户名并返回用户名类型
     * @param $username [string] 【用户名可能是邮箱，也可能是手机号】
     * @return string     【检测结果】
     */
    public function check_username ($username) {
        /** 判断是否为邮箱*/
        $is_email = Validate::is($username, 'email') ? 1 : 0;
        /** 判读是否为手机号*/
        $is_phone = preg_match('/^1[34578]\d{9}$/', $username) ? 4 : 2;
        /** 最终结果*/
        $flag = $is_email + $is_phone;
        switch ($flag) {
            /** 非手机号  非邮箱*/
            case 2:
                $this->message(400, '手机号或邮箱不正确');
                break;
            /** 用户名为邮箱*/
            case 3:
                return 'email';
                break;
            /** 用户名为手机号*/
            case 4:
                return 'phone';
                break;
        }
    }

    /**
     * 判断用户是否存在
     * @param $value  【用户名】
     * @param $type     【用户名类型】
     * @param $exist
     */
    public function check_exist ($value, $type, $exist) {
        $type_num = $type == "phone" ? 2 : 4;
        $flag = $type_num + $exist;
        $phone_res = db('user')->where('user_phone', $value)->find();
        $email_res = db('user')->where('user_email', $value)->find();
        switch ($flag) {
            /** 手机号码已被占用*/
            case    2:
                if ($phone_res) {
                    $this->message(400, '手机号已被占用啦');
                }
                break;
            /** 手机号码不存在*/
            case 3:
                if (!$phone_res) {
                    $this->message(400, '手机号码不存在');
                }
                break;
            /** 邮箱已被占用*/
            case 4:
                if ($email_res) {
                    $this->message(400, '邮箱已被占用');
                }
                break;
            /** 邮箱不存在*/
            case 5:
                if (!$email_res) {
                    $this->message(400, '邮箱不存在');
                }
                break;
        }
    }

    /**
     * 验证验证码
     * @param $user_name
     * @param $code
     */
    public function check_code ($user_name, $code) {
        /** 检测是否超时*/
        $last_time = session($user_name . '_last_send_time');
        if (time() - $last_time > 6000) {
            $this->message(400, '验证超时，请在一分钟内验证');
        }
        /** 检测验证码是否正确*/
        if (session($user_name . '_code') != $code) {
            var_dump(session($user_name . '_code'));
            var_dump($code);
            $this->message(400, '验证码不正确');
        }
        /*********** 不管正确或不正确，每个验证码只验证一次 ************/
//        session($user_name . '_code', null);
    }

    /**
     * 上传文件
     * @param $file
     * @param string $type
     * @return mixed
     */
    public function upload_file ($file, $type = '') {
        $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
        if ($info) {
            $path = '/uploads/' . $info->getSaveName();
            /** 裁剪图片*/
            if (!empty($type)) {
                $this->image_edit($path, $type);
            }
            return str_replace('\\', '/', $path);
        } else {
            $this->message(400, $file->getError());
        }
    }

    /**
     * 图片编辑
     * @param $path
     * @param $type
     */
    public function image_edit ($path, $type) {
        $image = Image::open(ROOT_PATH . 'public' . $path);
        switch ($type) {
            case    'head_img':
                $image->thumb(200, 200, Image::THUMB_CENTER)->save(ROOT_PATH . 'public' . $path);
        }
    }
}